<!-- 路径规划组件 -->
<!-- 操作：面板上选择起点和终点，然后点击进入规划模式，进行路径规划 -->
<!-- 路径规划期间，将禁用图层控制，并将图层隐藏，展示路径规划实体以及规划面板 -->
<!-- 点击离开规划，恢复图层控制，并清除规划的结果，隐藏规划面板 -->
<template>
  <div class="route-design-wrapper">
    <div class="route-design">
      <div class="header">
        <i class="iconfont metro-lujingguihua"></i>
        <span>路径规划</span>
        <button class="start-btn" @click="enterDesign">
          {{ isDesign ? "离开规划模式" : "进入规划模式" }}
        </button>
      </div>
      <div class="content">
        <div>
          <span style="margin-right: 5px">起点:</span>
          <a-cascader
            v-model:value="startStation"
            :options="options"
            placeholder="请输入起点站"
          >
            <template #clearIcon>
              <i class="iconfont metro-close"></i>
            </template>
          </a-cascader>
          <!-- <a-button style="margin-left: 8px" @click="pickStation('origin')">拾取起点站</a-button> -->
        </div>
        <div>
          <span style="margin-right: 5px">终点:</span>
          <a-cascader
            v-model:value="endStation"
            :options="options"
            placeholder="请输入起点站"
            ><template #clearIcon>
              <i class="iconfont metro-close"></i>
            </template>
          </a-cascader>
        </div>
      </div>
    </div>
  </div>
  <!-- 路径规划展示面板 -->
  <PathDesignDisplayCard
    :routeInfo="routeInfo"
    v-if="isDesign"
    :cacheData="cacheData"
  />
</template>
<script setup>
import { ref, onMounted, watch, onBeforeUnmount } from "vue";
import { message } from "ant-design-vue"; // 引入ant-design-vue的message组件
import {
  renderStation,
  renderStationBill,
  renderLines,
  removeAll,
  removeByCacheData,
  flyToDefaultView,
} from "@/cesiumTools/effectController"; // 引入地图相关的工具函数
import { getLinePlan } from "@/api/line"; // 引入路径规划服务
import PathDesignDisplayCard from "./PathDesignDisplayCard.vue"; // 引入路径规划展示面板组件
import { useLineData } from "@/store";
import { lineColors } from "@/store/staticData";

const lineDataStore = useLineData();
// 定义响应式变量
let viewer; // 地图查看器
let subLineData = ref([]);
let startStation = ref([]); // 起点站
let endStation = ref([]); // 终点站
let isDesign = ref(false); // 是否处于规划模式
let pathInfo = ref({}); // 路径规划信息
let routeInfo = ref({}); // 路径信息
let cacheData = {
  billboards: [], // 站点标记
  lineEnts: [], // 路径实体
  stationEnts: [], // 站点实体
};

// 渲染下拉列表的数据
let options = ref([]);
onMounted(() => {
  viewer = lineDataStore.Viewer;
  subLineData.value = lineDataStore.allData;
  if (subLineData.value.length > 0) {
    options.value = subLineData.value.map((item) => {
      const { name, stationsList } = item;
      const children = stationsList.map((s) => ({
        value: s.name,
        label: s.name,
      }));
      return {
        label: name,
        value: name,
        children,
      };
    });
  }
});

watch([startStation, endStation], async (value) => {
  // console.log(value);
  //设置
  if (isDesign.value) {
    // console.log(value, "value");
    //获取路线的起始坐标
    const data = await getLineData();
    pathInfo.value = data;
    mapChange();
  }
});
//坐标信息
const getPositon = (lineName, stationName) => {
  const targetLine = subLineData.value.find((l) => l.name === lineName);
  const { position } = targetLine.stationsList.find(
    (s) => s.name === stationName
  );
  return `${position.lng},${position.lat}`;
};
//线路规划
const getLineData = async () => {
  const start = startStation.value;
  const end = endStation.value;
  // console.log(start, end, "11111");
  //如果起点和终点都填入了数据，就跑服务，获取路径规划数据
  if (start.length && end.length) {
    let params = {};
    // 从lineData中获取坐标信息
    params.origin = getPositon(start[0], start[1]);
    params.destination = getPositon(end[0], end[1]);
    // console.log("params", params);
    const { code, data } = await getLinePlan(params);
    if (code === 200) {
      return data;
    } else {
      message.warn("查询不到相关数据");
      return null;
    }
  }
};

const mapChange = () => {
  // 清除之前的道路规划实体
  removeActiveEnts();
  // 第二步,通过数据，渲染站点与路径
  // 获取到所有的站点与路径，渲染地图效果
  const stations = [];
  const paths = [];
  const route = {
    stations: [],
  };
  if (pathInfo.value != {}) {
    const { distance, segments } = pathInfo.value;
    // console.log(pathInfo.value, "pathInfo2");
    // console.log(segments, "segments");
    route.distance = distance;
    // 处理换乘站逻辑，每一段线路的末尾，给上换乘type
    segments.forEach((s, sIndex) => {
      // buslines可能为null
      const {
        bus: { buslines },
      } = s;
      if (buslines?.length) {
        const target = buslines[0];
        const color = lineColors[sIndex];
        target.color = color;
        route.stations.push(target);

        buslines.forEach((b, index) => {
          const line = { part: index + 1, partStation: [] };
          const {
            type,
            arrival_stop,
            departure_stop,
            name,
            polyline,
            via_stops,
          } = b;
          paths.push({
            name,
            part: index + 1,
            polyline,
          });
          if (type === "地铁线路") {
            // 先加入起点站
            let arrival = arrival_stop;
            let departure = departure_stop;
            // 如果是最后一段线路，为终点站，否则为换乘站
            arrival.type = sIndex === segments.length - 1 ? "终点站" : "换乘站";
            // 如果是第一段线路，为起点站，否则为换乘站
            departure.type = sIndex === 0 ? "起点站" : "换乘站";

            line.partStation.push(arrival);
            via_stops.forEach((v) => {
              v.type = "途径站";
              line.partStation.push(v);
            });

            line.partStation.push(departure);
            line.name = name;
          }
          stations.push(line);
          // console.log(stations, "stations");
        });
      }
    });
  }

  routeInfo.value = route;
  // console.log(routeInfo.value, "routeInfo.value");
  // 第二步，渲染站点以及路径,不走effectController内部缓存
  stations.forEach((station, index) => {
    let color = lineColors[index];
    const { partStation } = station;
    // 添加站点
    partStation.forEach(async (p) => {
      let { location, name, type } = p;
      name = type === "换乘站" ? name + "(换乘)" : name;
      const positionArr = location.split(",").map((item) => Number(item));
      const positions = { lng: positionArr[0], lat: positionArr[1] };
      // 这里不能走缓存，因为name不一样，会污染后续的功能
      const stationEnt = renderStation(viewer, {
        positions,
        name,
        color: type === "换乘站" ? "#e9a526" : color,
      });
      const billboard = await renderStationBill(viewer, {
        positions,
        name,
        color: type === "换乘站" ? "#e9a526" : color,
        attr: {
          name,
        },
      });
      // 存放在组件中
      cacheData.stationEnts.push(stationEnt);
      cacheData.billboards.push(billboard);
      //   console.log("cacheData", cacheData.stationEnts.length)
    });
  });

  // // 添加路径,处理路径坐标
  paths.forEach((path, index) => {
    const color = lineColors[index];
    const {
      polyline: { polyline },
      name,
    } = path;
    let positionList = polyline.split(";");
    positionList = positionList.map((pos, index) => {
      const [lng, lat] = pos.split(",").map((item) => Number(item));
      return {
        lng: Number(lng),
        lat: Number(lat),
      };
    });
    // console.log(positionList, "positionList111111111")
    //把这里的positionList从数组对象转为一维数组
    /* const flattenedPositions = options.map((item) =>
      item.positions.flatMap((pos) => [pos.lng, pos.lat])
    ); */
    const flattenedPositions = positionList.flatMap((pos) => [
      pos.lng,
      pos.lat,
    ]);
    // console.log(flattenedPositions, "flattenedPositions");

    const lineEnt = renderLines(viewer, {
      positions: flattenedPositions,
      name,
      color: Cesium.Color.fromCssColorString(color),
    });
    cacheData.lineEnts.push(lineEnt);
  });
  flyToDefaultView(viewer);
};
// 进入规划模式
const enterDesign = async () => {
  if (!Object.keys(pathInfo.value).length) {
    // 检查是否有起点终点站
    if (startStation.value.length && endStation.value.length) {
      // 将站点站线全部隐藏
      const lineNames = lineDataStore.allData.map((item) => item.name);
      // console.log(lineNames);
      lineDataStore.displayLine(lineNames, false);
      // 暂时禁用全局管理，unMount的时候打开
      lineDataStore.disableController(true);

      //删除实体
      removeAll(viewer);
      // 如果存在的话，跑服务，填充pathInfo
      const data = await getLineData();
      pathInfo.value = data;
    } else {
      message.warn("请先选择起点和终点站点");
      return;
    }
  }
  // 如果处于规划模式，就退出
  if (isDesign.value) {
    leaveRouteDesign();
    return;
  }
  // 进入规划模式第一步，隐藏当前地图上所有的元素
  // 我们直接交给图层控制组件完成这一步
  // lineData.controlAll(false)
  // 第二步，渲染效果
  mapChange();
  isDesign.value = true;
};

// 删除规划实体
const removeActiveEnts = () => {
  removeByCacheData(viewer, cacheData);
  cacheData.billboards = [];
  cacheData.lineEnts = [];
  cacheData.stationEnts = [];
};

// 离开规划模式
const leaveRouteDesign = () => {
  removeActiveEnts();
  // lineData.controlAll(true)
  isDesign.value = false;
  startStation.value = [];
  endStation.value = [];
  pathInfo.value = {};

  // 全局管理恢复，路线展示恢复
  lineDataStore.disableController(false);
  // 将站点站线全部展示
  const lineNames = lineDataStore.allData.map((item) => item.name);
  lineDataStore.displayLine(lineNames, true);
};

//监听路由变化,组件销毁时，清除缓存数据
onBeforeUnmount(() => {
  leaveRouteDesign();
});
</script>
<style scoped>
/* 路径规划样式 */
.route-design-wrapper {
  position: absolute;
  left: 700%;
  top: -5%;
}

.route-design {
  width: 320px;
  height: 170px;
  background-color: rgba(0, 0, 0, 0.6);
  border: 1px solid #885f12;
}

.route-design > .header {
  width: 100%;
  height: 40px;
  color: #fff;
  padding-left: 10px;
  background: rgb(255, 255, 255);
  background-image: linear-gradient(
    180deg,
    rgba(255, 255, 255, 1) 9%,
    rgba(211, 156, 50, 1) 57%
  );
  /* -webkit-background-clip: text; */
  background-clip: text;
  -webkit-text-fill-color: transparent;
  display: flex;
  align-items: center;
}

.route-design span {
  margin-left: 5px;
}

.content {
  width: 100%;
  height: 110px;
  pointer-events: all;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-around;
  color: #fff;
}

.start-btn {
  width: 80px;
  color: #fff;
  margin-left: 140px;
  background-color: transparent;
  border: 1px solid #885f12;
  font-size: 12px;
  padding: 3px;
  pointer-events: all;
  cursor: pointer;
}

.start-btn:hover {
  background-color: #5c3f096d;
  border: 1px solid #881212;
}
</style>
